from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.core.cache import cache

from app01.utils.form.bootsrapform import BootStrapForm, BootStrapModelForm
from app01 import models
from app01.utils.encrypt import md5

class SendMailRegisterForm(BootStrapForm):
    """ 发送短信 """
    # 简易邮箱正则效验
    pattern = r"^[a-zA-Z0-9][a-zA-Z0-9._%+-]{0,63}@[a-zA-Z0-9-]+\.[a-zA-Z]{2,6}$"
    usermail = forms.CharField(
        label="邮箱",
        validators=[RegexValidator(pattern,'邮箱格式错误'),],
        widget=forms.EmailInput,
        required=True,
    )
    def clean_usermail(self):
        usermail = self.cleaned_data.get('usermail')
        user_object_exists = models.User.objects.filter(usermail=usermail).exists()
        if user_object_exists:
            raise ValidationError("邮箱已存在")
        return  usermail

class RegisterModelForm(BootStrapModelForm):
    """ 注册ModelForm """
    usermail = forms.CharField(
        label="邮箱",
        widget=forms.EmailInput,
        required=True,
        strip=True,
    )
    code = forms.CharField(
        label="邮箱验证码",
        widget=forms.TextInput(attrs={'autocomplete': 'off'}),
        required=True,
        strip=True,
    )
    password = forms.CharField(
        label="密码",
        min_length=8,
        max_length=16,
        error_messages={
            'min_length': "密码长度不能小于8个字符",
            'max_length':"密码长度不能大于16个字符",
        },
        widget=forms.PasswordInput(render_value=True),
        required=True,
    )
    confirm_password =forms.CharField(
        label="确认密码",
        widget=forms.PasswordInput(render_value=True) ,# 不记录历史输入
        required=True
    )

    class Meta:
        model = models.User
        fields = ["usermail","password", "confirm_password", "code"]

    def clean_password(self):
        pwd = self.cleaned_data.get("password")
        return md5(pwd)
    
    def clean_confirm_password(self):
        pwd = self.cleaned_data.get("password")
        confirm = md5(self.cleaned_data.get("confirm_password"))
        if confirm != pwd:
            raise ValidationError("密码不一致")
            #返回什么，此字段以后保存到数据库就是什么。
        return confirm
    
    def clean_usermail(self):
        usermail = self.cleaned_data.get('usermail')
        user_object_exists = models.User.objects.filter(usermail=usermail).exists()
        if user_object_exists:
            raise ValidationError("邮箱已存在")
        return usermail  
    
    def clean_code(self):

        code = self.cleaned_data.get('code')
        usermail = (self.cleaned_data.get('usermail') or '').strip().lower()
        
        redis_key = f'verify:{usermail}'

        # 从Redis获取验证码（键名必须和存储时一致）
        redis_code = cache.get(redis_key)

        if not redis_code:
            raise ValidationError("验证码失效或未发送, 请重新发送")
        
        str_redis_code = str(redis_code)# 确保转为字符串
        
        if code != str_redis_code:
            raise ValidationError("验证码错误, 请重新输入")
        
        return code
        
class LoginForm(BootStrapForm):

    usermail = forms.CharField(
        label="邮箱",
        widget=forms.EmailInput,
        required=True
    )

    password = forms.CharField(
        label="密码",
        widget=forms.PasswordInput(render_value=True),
        required=True,
    )
    code = forms.CharField(
        label="验证码",
        widget=forms.TextInput(attrs={'autocomplete': 'off'}),
        required=True,
    )

    def clean_password(self):
        pwd = self.cleaned_data.get("password")
        return md5(pwd)

# 继承即可
class ForgotPasswordModelForm(RegisterModelForm):
    """ 忘记密码ModelForm """
    def clean_usermail(self):
        """ 邮箱存在才允许发验证码 """
        usermail = self.cleaned_data.get('usermail')
        user_object_exists = models.User.objects.filter(usermail=usermail).exists()
        if user_object_exists:
            return usermail  
        raise ValidationError("邮箱不存在, 请先注册")
    

    
    def clean_password(self):
        pwd = self.cleaned_data.get("password")
        usermail = self.cleaned_data.get("usermail")
        
        md5_pwd = md5(pwd)

        # 去数据库校验与当前密码不同
        # 扩展: self.instance.pk 是主键（Primary Key）
        exists = models.User.objects.filter(usermail=usermail,password=md5_pwd).exists()
        if exists:
            raise ValidationError("密码不能与当前相同")
        return md5_pwd
    
    
class SendMailForgotPassword(SendMailRegisterForm):
    def clean_usermail(self):
        usermail = self.cleaned_data.get('usermail')
        user_object_exists = models.User.objects.filter(usermail=usermail).exists()
        if user_object_exists:
           return  usermail
        raise ValidationError("邮箱不存在")
    

    

    